part of '../widgets.dart';

/// [VanButton]属性常量
const kVanButtonMiniHeight = VanCssKey._raw('--van-button-mini-height');
const kVanButtonMiniPadding = VanCssKey._raw('--van-button-mini-padding');
const kVanButtonMiniFontSize = VanCssKey._raw('--van-button-mini-font-size');
const kVanButtonSmallHeight = VanCssKey._raw('--van-button-small-height');
const kVanButtonSmallPadding = VanCssKey._raw('--van-button-small-padding');
const kVanButtonSmallFontSize = VanCssKey._raw('--van-button-small-font-size');
const kVanButtonNormalPadding = VanCssKey._raw('--van-button-normal-padding');
const kVanButtonNormalFontSize = VanCssKey._raw('--van-button-normal-font-size');
const kVanButtonLargeHeight = VanCssKey._raw('--van-button-large-height');
const kVanButtonDefaultHeight = VanCssKey._raw('--van-button-default-height');
const kVanButtonDefaultLineHeight = VanCssKey._raw('--van-button-default-line-height');
const kVanButtonDefaultFontSize = VanCssKey._raw('--van-button-default-font-size');
const kVanButtonDefaultColor = VanCssKey._raw('--van-button-default-color');
const kVanButtonDefaultBackground = VanCssKey._raw('--van-button-default-background');
const kVanButtonDefaultBorderColor = VanCssKey._raw('--van-button-default-border-color');
const kVanButtonPrimaryColor = VanCssKey._raw('--van-button-primary-color');
const kVanButtonPrimaryBackground = VanCssKey._raw('--van-button-primary-background');
const kVanButtonPrimaryBorderColor = VanCssKey._raw('--van-button-primary-border-color');
const kVanButtonSuccessColor = VanCssKey._raw('--van-button-success-color');
const kVanButtonSuccessBackground = VanCssKey._raw('--van-button-success-background');
const kVanButtonSuccessBorderColor = VanCssKey._raw('--van-button-success-border-color');
const kVanButtonDangerColor = VanCssKey._raw('--van-button-danger-color');
const kVanButtonDangerBackground = VanCssKey._raw('--van-button-danger-background');
const kVanButtonDangerBorderColor = VanCssKey._raw('--van-button-danger-border-color');
const kVanButtonWarningColor = VanCssKey._raw('--van-button-warning-color');
const kVanButtonWarningBackground = VanCssKey._raw('--van-button-warning-background');
const kVanButtonWarningBorderColor = VanCssKey._raw('--van-button-warning-border-color');
const kVanButtonBorderWidth = VanCssKey._raw('--van-button-border-width');
const kVanButtonRadius = VanCssKey._raw('--van-button-radius');
const kVanButtonRoundRadius = VanCssKey._raw('--van-button-round-radius');
const kVanButtonPlainBackground = VanCssKey._raw('--van-button-plain-background');
const kVanButtonDisabledOpacity = VanCssKey._raw('--van-button-disabled-opacity');
const kVanButtonIconSize = VanCssKey._raw('--van-button-icon-size');
const kVanButtonLoadingIconSize = VanCssKey._raw('--van-button-loading-icon-size');

/// [VanButton]主题类
@immutable
class VanButtonTheme extends VanProvider<VanButtonThemeData> with VanProvide {
  const VanButtonTheme({super.key, required super.child, required super.provide});

  static VanButtonThemeData of(BuildContext context) => VanProvider.of<VanButtonTheme>(context)?.provide ?? VanTheme.of(context).buttonTheme;
  static const _prefix = "--van-button-";

  static bool support(VanCssKey key) => key.key.startsWith(_prefix);

  static dynamic get<T>(BuildContext context, {required VanCssKey key, T? defaultValue}) {
    final VanButtonThemeData buttonTheme = VanButtonTheme.of(context);
    if (kVanButtonMiniHeight == key) return buttonTheme.miniHeight.get(context);
    if (kVanButtonMiniPadding == key) return buttonTheme.miniPadding.get(context);
    if (kVanButtonMiniFontSize == key) return buttonTheme.miniFontSize.get(context);
    if (kVanButtonSmallHeight == key) return buttonTheme.smallHeight.get(context);
    if (kVanButtonSmallPadding == key) return buttonTheme.smallPadding.get(context);
    if (kVanButtonSmallFontSize == key) return buttonTheme.smallFontSize.get(context);
    if (kVanButtonNormalPadding == key) return buttonTheme.normalPadding.get(context);
    if (kVanButtonNormalFontSize == key) return buttonTheme.normalFontSize.get(context);
    if (kVanButtonLargeHeight == key) return buttonTheme.largeHeight.get(context);
    if (kVanButtonDefaultHeight == key) return buttonTheme.defaultHeight.get(context);
    if (kVanButtonDefaultLineHeight == key) return buttonTheme.defaultLineHeight.get(context);
    if (kVanButtonDefaultFontSize == key) return buttonTheme.defaultFontSize.get(context);
    if (kVanButtonDefaultColor == key) return buttonTheme.defaultColor.get(context);
    if (kVanButtonDefaultBackground == key) return buttonTheme.defaultBackground.get(context);
    if (kVanButtonDefaultBorderColor == key) return buttonTheme.defaultBorderColor.get(context);
    if (kVanButtonPrimaryColor == key) return buttonTheme.primaryColor.get(context);
    if (kVanButtonPrimaryBackground == key) return buttonTheme.primaryBackground.get(context);
    if (kVanButtonPrimaryBorderColor == key) return buttonTheme.primaryBorderColor.get(context);
    if (kVanButtonSuccessColor == key) return buttonTheme.successColor.get(context);
    if (kVanButtonSuccessBackground == key) return buttonTheme.successBackground.get(context);
    if (kVanButtonSuccessBorderColor == key) return buttonTheme.successBorderColor.get(context);
    if (kVanButtonDangerColor == key) return buttonTheme.dangerColor.get(context);
    if (kVanButtonDangerBackground == key) return buttonTheme.dangerBackground.get(context);
    if (kVanButtonDangerBorderColor == key) return buttonTheme.dangerBorderColor.get(context);
    if (kVanButtonWarningColor == key) return buttonTheme.warningColor.get(context);
    if (kVanButtonWarningBackground == key) return buttonTheme.warningBackground.get(context);
    if (kVanButtonWarningBorderColor == key) return buttonTheme.warningBorderColor.get(context);
    if (kVanButtonBorderWidth == key) return buttonTheme.borderWidth.get(context);
    if (kVanButtonRadius == key) return buttonTheme.radius.get(context);
    if (kVanButtonRoundRadius == key) return buttonTheme.roundRadius.get(context);
    if (kVanButtonPlainBackground == key) return buttonTheme.plainBackground.get(context);
    if (kVanButtonDisabledOpacity == key) return buttonTheme.disabledOpacity.get(context);
    if (kVanButtonIconSize == key) return buttonTheme.iconSize.get(context);
    if (kVanButtonLoadingIconSize == key) return buttonTheme.loadingIconSize.get(context);
    return null;
  }
}

/// [VanButton]主题数据类
@immutable
class VanButtonThemeData with VanProvide {
  final VanCss<double> miniHeight;
  final VanCss<EdgeInsets> miniPadding;
  final VanCss<double> miniFontSize;
  final VanCss<double> smallHeight;
  final VanCss<EdgeInsets> smallPadding;
  final VanCss<double> smallFontSize;
  final VanCss<EdgeInsets> normalPadding;
  final VanCss<double> normalFontSize;
  final VanCss<double> largeHeight;
  final VanCss<double> defaultHeight;
  final VanCss<double> defaultLineHeight;
  final VanCss<double> defaultFontSize;
  final VanCss<Color> defaultColor;
  final VanCss<VanBgColor> defaultBackground;
  final VanCss<Color> defaultBorderColor;
  final VanCss<Color> primaryColor;
  final VanCss<VanBgColor> primaryBackground;
  final VanCss<Color> primaryBorderColor;
  final VanCss<Color> successColor;
  final VanCss<VanBgColor> successBackground;
  final VanCss<Color> successBorderColor;
  final VanCss<Color> dangerColor;
  final VanCss<VanBgColor> dangerBackground;
  final VanCss<Color> dangerBorderColor;
  final VanCss<Color> warningColor;
  final VanCss<VanBgColor> warningBackground;
  final VanCss<Color> warningBorderColor;
  final VanCss<double> borderWidth;
  final VanCss<BorderRadius> radius;
  final VanCss<BorderRadius> roundRadius;
  final VanCss<VanBgColor> plainBackground;
  final VanCss<double> disabledOpacity;
  final VanCss<double> iconSize;
  final VanCss<double> loadingIconSize;

  /// 构造器
  const VanButtonThemeData.raw({
    required this.miniHeight,
    required this.miniPadding,
    required this.miniFontSize,
    required this.smallHeight,
    required this.smallPadding,
    required this.smallFontSize,
    required this.normalPadding,
    required this.normalFontSize,
    required this.largeHeight,
    required this.defaultHeight,
    required this.defaultLineHeight,
    required this.defaultFontSize,
    required this.defaultColor,
    required this.defaultBackground,
    required this.defaultBorderColor,
    required this.primaryColor,
    required this.primaryBackground,
    required this.primaryBorderColor,
    required this.successColor,
    required this.successBackground,
    required this.successBorderColor,
    required this.dangerColor,
    required this.dangerBackground,
    required this.dangerBorderColor,
    required this.warningColor,
    required this.warningBackground,
    required this.warningBorderColor,
    required this.borderWidth,
    required this.radius,
    required this.roundRadius,
    required this.plainBackground,
    required this.disabledOpacity,
    required this.iconSize,
    required this.loadingIconSize,
  });

  /// 拷贝
  VanButtonThemeData copyFrom({
    VanCss<double>? miniHeight,
    VanCss<EdgeInsets>? miniPadding,
    VanCss<double>? miniFontSize,
    VanCss<double>? smallHeight,
    VanCss<EdgeInsets>? smallPadding,
    VanCss<double>? smallFontSize,
    VanCss<EdgeInsets>? normalPadding,
    VanCss<double>? normalFontSize,
    VanCss<double>? largeHeight,
    VanCss<double>? defaultHeight,
    VanCss<double>? defaultLineHeight,
    VanCss<double>? defaultFontSize,
    VanCss<Color>? defaultColor,
    VanCss<VanBgColor>? defaultBackground,
    VanCss<Color>? defaultBorderColor,
    VanCss<Color>? primaryColor,
    VanCss<VanBgColor>? primaryBackground,
    VanCss<Color>? primaryBorderColor,
    VanCss<Color>? successColor,
    VanCss<VanBgColor>? successBackground,
    VanCss<Color>? successBorderColor,
    VanCss<Color>? dangerColor,
    VanCss<VanBgColor>? dangerBackground,
    VanCss<Color>? dangerBorderColor,
    VanCss<Color>? warningColor,
    VanCss<VanBgColor>? warningBackground,
    VanCss<Color>? warningBorderColor,
    VanCss<double>? borderWidth,
    VanCss<BorderRadius>? radius,
    VanCss<BorderRadius>? roundRadius,
    VanCss<VanBgColor>? plainBackground,
    VanCss<double>? disabledOpacity,
    VanCss<double>? iconSize,
    VanCss<double>? loadingIconSize,
  }) {
    return VanButtonThemeData.raw(
      miniHeight: miniHeight ?? this.miniHeight,
      miniPadding: miniPadding ?? this.miniPadding,
      miniFontSize: miniFontSize ?? this.miniFontSize,
      smallHeight: smallHeight ?? this.smallHeight,
      smallPadding: smallPadding ?? this.smallPadding,
      smallFontSize: smallFontSize ?? this.smallFontSize,
      normalPadding: normalPadding ?? this.normalPadding,
      normalFontSize: normalFontSize ?? this.normalFontSize,
      largeHeight: largeHeight ?? this.largeHeight,
      defaultHeight: defaultHeight ?? this.defaultHeight,
      defaultLineHeight: defaultLineHeight ?? this.defaultLineHeight,
      defaultFontSize: defaultFontSize ?? this.defaultFontSize,
      defaultColor: defaultColor ?? this.defaultColor,
      defaultBackground: defaultBackground ?? this.defaultBackground,
      defaultBorderColor: defaultBorderColor ?? this.defaultBorderColor,
      primaryColor: primaryColor ?? this.primaryColor,
      primaryBackground: primaryBackground ?? this.primaryBackground,
      primaryBorderColor: primaryBorderColor ?? this.primaryBorderColor,
      successColor: successColor ?? this.successColor,
      successBackground: successBackground ?? this.successBackground,
      successBorderColor: successBorderColor ?? this.successBorderColor,
      dangerColor: dangerColor ?? this.dangerColor,
      dangerBackground: dangerBackground ?? this.dangerBackground,
      dangerBorderColor: dangerBorderColor ?? this.dangerBorderColor,
      warningColor: warningColor ?? this.warningColor,
      warningBackground: warningBackground ?? this.warningBackground,
      warningBorderColor: warningBorderColor ?? this.warningBorderColor,
      borderWidth: borderWidth ?? this.borderWidth,
      radius: radius ?? this.radius,
      roundRadius: roundRadius ?? this.roundRadius,
      plainBackground: plainBackground ?? this.plainBackground,
      disabledOpacity: disabledOpacity ?? this.disabledOpacity,
      iconSize: iconSize ?? this.iconSize,
      loadingIconSize: loadingIconSize ?? this.loadingIconSize,
    );
  }

  /// 反序列化
  static VanButtonThemeData fromJson(Map<String, dynamic> json) {
    return VanButtonThemeData.raw(
      miniHeight: VanCss(json[kVanButtonMiniHeight.key]),
      miniPadding: VanCss(json[kVanButtonMiniPadding.key]),
      miniFontSize: VanCss(json[kVanButtonMiniFontSize.key]),
      smallHeight: VanCss(json[kVanButtonSmallHeight.key]),
      smallPadding: VanCss(json[kVanButtonSmallPadding.key]),
      smallFontSize: VanCss(json[kVanButtonSmallFontSize.key]),
      normalPadding: VanCss(json[kVanButtonNormalPadding.key]),
      normalFontSize: VanCss(json[kVanButtonNormalFontSize.key]),
      largeHeight: VanCss(json[kVanButtonLargeHeight.key]),
      defaultHeight: VanCss(json[kVanButtonDefaultHeight.key]),
      defaultLineHeight: VanCss(json[kVanButtonDefaultLineHeight.key]),
      defaultFontSize: VanCss(json[kVanButtonDefaultFontSize.key]),
      defaultColor: VanCss(json[kVanButtonDefaultColor.key]),
      defaultBackground: VanCss(json[kVanButtonDefaultBackground.key]),
      defaultBorderColor: VanCss(json[kVanButtonDefaultBorderColor.key]),
      primaryColor: VanCss(json[kVanButtonPrimaryColor.key]),
      primaryBackground: VanCss(json[kVanButtonPrimaryBackground.key]),
      primaryBorderColor: VanCss(json[kVanButtonPrimaryBorderColor.key]),
      successColor: VanCss(json[kVanButtonSuccessColor.key]),
      successBackground: VanCss(json[kVanButtonSuccessBackground.key]),
      successBorderColor: VanCss(json[kVanButtonSuccessBorderColor.key]),
      dangerColor: VanCss(json[kVanButtonDangerColor.key]),
      dangerBackground: VanCss(json[kVanButtonDangerBackground.key]),
      dangerBorderColor: VanCss(json[kVanButtonDangerBorderColor.key]),
      warningColor: VanCss(json[kVanButtonWarningColor.key]),
      warningBackground: VanCss(json[kVanButtonWarningBackground.key]),
      warningBorderColor: VanCss(json[kVanButtonWarningBorderColor.key]),
      borderWidth: VanCss(json[kVanButtonBorderWidth.key]),
      radius: VanCss(json[kVanButtonRadius.key]),
      roundRadius: VanCss(json[kVanButtonRoundRadius.key]),
      plainBackground: VanCss(json[kVanButtonPlainBackground.key]),
      disabledOpacity: VanCss(json[kVanButtonDisabledOpacity.key]),
      iconSize: VanCss(json[kVanButtonIconSize.key]),
      loadingIconSize: VanCss(json[kVanButtonLoadingIconSize.key]),
    );
  }
}

/// [VanButton]样式
@immutable
class VanButtonStyle with VanProvide {
  static of(BuildContext context) => VanProvider.of<VanButtonStyle>(context);
  final double? width;
  final double? height;
  final EdgeInsets? padding;
  final double? fontSize;
  final double? lineHeight;
  final Color? color;
  final VanBgColor? background;
  final Color? borderColor;
  final double? borderWidth;
  final BorderRadius? radius;
  final double? opacity;
  final double? iconSize;
  final double? loadingIconSize;

  VanButtonStyle({
    this.width,
    this.height,
    this.padding,
    this.fontSize,
    this.lineHeight,
    this.color,
    this.background,
    this.borderColor,
    this.borderWidth,
    this.radius,
    this.opacity,
    this.iconSize,
    this.loadingIconSize,
  });

  bool get isNonNull {
    if (width == null) return false;
    if (height == null) return false;
    if (padding == null) return false;
    if (fontSize == null) return false;
    if (lineHeight == null) return false;
    if (color == null) return false;
    if (background == null) return false;
    if (borderColor == null) return false;
    if (borderWidth == null) return false;
    if (radius == null) return false;
    if (opacity == null) return false;
    if (iconSize == null) return false;
    if (loadingIconSize == null) return false;
    return true;
  }

  VanButtonStyle copyFrom({
    double? width,
    double? height,
    EdgeInsets? padding,
    double? fontSize,
    double? lineHeight,
    Color? color,
    VanBgColor? background,
    Color? borderColor,
    double? borderWidth,
    BorderRadius? radius,
    double? opacity,
    double? iconSize,
    double? loadingIconSize,
  }) {
    return VanButtonStyle(
      width: width ?? this.width,
      height: height ?? this.height,
      padding: padding ?? this.padding,
      fontSize: fontSize ?? this.fontSize,
      lineHeight: lineHeight ?? this.lineHeight,
      color: color ?? this.color,
      background: background ?? this.background,
      borderColor: borderColor ?? this.borderColor,
      borderWidth: borderWidth ?? this.borderWidth,
      radius: radius ?? this.radius,
      opacity: opacity ?? this.opacity,
      iconSize: iconSize ?? this.iconSize,
      loadingIconSize: loadingIconSize ?? this.loadingIconSize,
    );
  }
}
